package toolsdk

import (
	"math/rand"
	"time"
)

/**
密码加/解密算法
*/
type ApiPwdDecryption struct {
	pwdSign   string   //密码加密过后的字符串
	pwd       string   //密码
	pwdPreFix []string //密码前缀
	errMsg    string   //解密错误信息
}

func (me *ApiPwdDecryption) SetPwdSign(pwdSign string) *ApiPwdDecryption {
	me.pwdSign = pwdSign
	return me
}

func (me *ApiPwdDecryption) GetPwdSign() string {
	return me.pwdSign
}

func (me *ApiPwdDecryption) SetPwd(pwd string) *ApiPwdDecryption {
	me.pwd = pwd
	return me
}

func (me *ApiPwdDecryption) GetPwd() string {
	return me.pwd
}

func (me *ApiPwdDecryption) SetPwdPreFix(pwdPreFix []string) *ApiPwdDecryption {
	me.pwdPreFix = pwdPreFix
	return me
}

func (me *ApiPwdDecryption) GetPwdPreFix() []string {
	if len(me.pwdPreFix) > 0 {
		return me.pwdPreFix
	}
	return []string{"P", "W", "D", "p", "w", "d"}
}

func (me *ApiPwdDecryption) SetErrMsg(errMsg string) *ApiPwdDecryption {
	me.errMsg = errMsg
	return me
}

func (me *ApiPwdDecryption) GetErrMsg() string {
	return me.errMsg
}

func (me *ApiPwdDecryption) Decryption() *ApiPwdDecryption {
	newPwd := ""

	pwdPreFixList := me.GetPwdPreFix()
	pwd := me.GetPwdSign()
	pwdList := []rune(pwd)
	pwdListLen := len(pwdList)

	nextI := 0
	for i, value := range pwdList {
		if nextI > 0 && nextI == i {
			continue
		}
		for _, pwdPreFix := range pwdPreFixList {
			if value == []rune(pwdPreFix)[0] {
				nextI = i + 1
				if nextI >= pwdListLen {
					me.SetErrMsg("密码格式不对")
					return me
				}
				newPwd += string(pwdList[nextI])
			}
		}
	}

	if newPwd == "" {
		me.SetErrMsg("密码解析为空")
		return me
	}

	me.SetPwd(newPwd)
	return me
}

func (me *ApiPwdDecryption) Encryption() *ApiPwdDecryption {
	rangList := []string{
		"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
		"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
		"1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
		"!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "+",
		"{", "}", "[", "]", ";", ":", "'", "\"", "<", ">", ",", ".", "?",
	}
	pwdPreFixList := me.GetPwdPreFix()

	getRandStr := func(l int) string {
		rL := len(rangList)
		str := ""
		for i := 0; i <= l; i++ {
			rand.Seed(time.Now().UnixNano())
			index := rand.Intn(rL)
			s := rangList[index]
			isExist := false
			for _, value := range pwdPreFixList {
				if []rune(s)[0] == []rune(value)[0] {
					isExist = true
					break
				}
			}
			if !isExist {
				str += s
			}
		}

		return str
	}

	pwd := me.GetPwd()
	pwdList := []rune(pwd)

	pwdStr := ""
	for _, value := range pwdList {
		rand.Seed(time.Now().UnixNano())
		//密码前缀
		pwdPreFixIndex := rand.Intn(len(pwdPreFixList))
		pwdPreFix := pwdPreFixList[pwdPreFixIndex]
		//干扰字符串
		signLen := rand.Intn(32) + 10
		randStr := getRandStr(signLen)
		//密码拼接
		pwdStr += randStr + pwdPreFix + string(value)
	}
	//增加结尾干扰字符串
	signLen := rand.Intn(32) + 10
	pwdStr += getRandStr(signLen)
	me.SetPwdSign(pwdStr)
	return me
}
